<template>
  <div class="app-container">
    <el-row :gutter="24">
      <el-col :span="6" :xs="24">
        <el-card class="box-card">
          <div slot="header" class="clearfix">
            <span>容器列表</span>
            <el-popover
              placement="right"
              trigger="hover"
              width="80"
            >
              <div>
                <div style="background-color: #909399; color: white">存储率 0%</div>
                <div style="background-color: #409EFF; margin-top: 2px; color: white">存储率 0%-40%</div>
                <div style="background-color: #67C23A; margin-top: 2px; color: white">存储率 40%-60%</div>
                <div style="background-color: #E6A23C; margin-top: 2px; color: white">存储率 60%-80%</div>
                <div style="background-color: #F56C6C; margin-top: 2px; color: white">存储率 80%-100%</div>
              </div>
              <i slot="reference" class="el-icon-question" style="margin-left: 5px"></i>
            </el-popover>
            <el-button
              v-hasPermi="['biobank:container:add']"
              icon="el-icon-plus"
              style="float: right; padding: 3px 0"
              type="text"
              @click="addOutsideArea"
            >添加分区
            </el-button>
          </div>
          <!-- 容器树 -->
          <el-tree
            ref="containerTree"
            :data="containerList"
            :default-expanded-keys="expandedKey"
            :expand-on-click-node="true"
            :load="loadLazyTree"
            :props="defaultProps"
            class="box-tree"
            lazy
            node-key="containerId"
            @node-contextmenu="rightClick"
            @node-click="nodeClick"
          >
            <span slot-scope="{ node, data }">
              <svg-icon :icon-class="data.containerIcon" style="margin-right: 3px"/>
              <span>{{ node.label }}</span>
              <span :style="judgeColor(data.storageRate)">{{ data.storageRate }}%</span>
            </span>
          </el-tree>
          <!-- 右键菜单 -->
          <div v-show="menuVisible" id="rightMenu" @mouseleave="menuVisible=!menuVisible">
            <el-card>
              <div v-if="menuType === 'outside_area'">
                <el-link v-hasPermi="['biobank:container:add']" :underline="false" @click="addTheContainer">
                  <svg-icon icon-class="fridge" style="margin-right: 5px"/>
                  添加容器
                </el-link>
                <div style="height: 10px"></div>
                <el-link v-hasPermi="['biobank:container:add']" :underline="false" icon="el-icon-copy-document"
                         @click="copyTheContainer"
                >复制分区
                </el-link>
                <div style="height: 10px"></div>
                <el-link v-hasPermi="['biobank:container:edit']" :underline="false" icon="el-icon-edit-outline"
                         @click="updateTheContainer"
                >修改分区
                </el-link>
                <div style="height: 10px"></div>
                <el-link v-hasPermi="['biobank:container:remove']" :underline="false" icon="el-icon-delete"
                         @click="deleteTheContainer"
                >删除分区
                </el-link>
              </div>
              <div v-if="menuType === 'fridge'">
                <el-link v-hasPermi="['biobank:container:add']" :underline="false" icon="el-icon-menu"
                         @click="addTheContainer"
                >添加容器分区
                </el-link>
                <div style="height: 10px"></div>
                <el-link v-hasPermi="['biobank:container:add']" :underline="false" icon="el-icon-takeaway-box"
                         @click="batchAddition"
                >批量添加
                </el-link>
                <div style="height: 10px"></div>
                <el-link v-hasPermi="['biobank:container:add']" :underline="false" icon="el-icon-copy-document"
                         @click="copyTheContainer"
                >复制分区
                </el-link>
                <div style="height: 10px"></div>
                <el-link v-hasPermi="['biobank:container:edit']" :underline="false" icon="el-icon-edit-outline"
                         @click="updateTheContainer"
                >修改容器
                </el-link>
                <div style="height: 10px"></div>
                <el-link v-hasPermi="['biobank:container:remove']" :underline="false" icon="el-icon-delete"
                         @click="deleteTheContainer"
                >删除容器
                </el-link>
              </div>
              <div v-if="menuType === 'inside_area'">
                <el-link v-hasPermi="['biobank:container:add']" :underline="false" icon="el-icon-menu"
                         @click="addTheContainer"
                >添加容器分区
                </el-link>
                <div style="height: 10px"></div>
                <el-link v-hasPermi="['biobank:container:add']" :underline="false" @click="addTheBox">
                  <svg-icon icon-class="box" style="margin-right: 5px"/>
                  添加冷冻盒
                </el-link>
                <div style="height: 10px"></div>
                <el-link v-hasPermi="['biobank:container:add']" :underline="false" icon="el-icon-copy-document"
                         @click="copyTheContainer"
                >复制分区
                </el-link>
                <div style="height: 10px"></div>
                <el-link v-hasPermi="['biobank:container:edit']" :underline="false" icon="el-icon-edit-outline"
                         @click="updateTheContainer"
                >修改容器分区
                </el-link>
                <div style="height: 10px"></div>
                <el-link v-hasPermi="['biobank:container:remove']" :underline="false" icon="el-icon-delete"
                         @click="deleteTheContainer"
                >删除容器分区
                </el-link>
              </div>
              <div v-if="menuType === 'boxes'">
                <el-link v-hasPermi="['biobank:container:add']" :underline="false" icon="el-icon-copy-document"
                         @click="copyTheBox"
                >复制冻存盒
                </el-link>
                <div style="height: 10px"></div>
                <el-link v-hasPermi="['biobank:container:edit']" :underline="false" icon="el-icon-edit-outline"
                         @click="updateTheContainer"
                >修改冻存盒
                </el-link>
                <div style="height: 10px"></div>
                <el-link v-hasPermi="['biobank:container:remove']" :underline="false" icon="el-icon-delete"
                         @click="deleteTheContainer"
                >删除冻存盒
                </el-link>
              </div>
            </el-card>
          </div>
        </el-card>
      </el-col>

      <el-col :span="18" :xs="24">
        <el-breadcrumb separator-class="el-icon-arrow-right">
          <el-breadcrumb-item>
            <svg-icon icon-class="fridge"/>
          </el-breadcrumb-item>
          <el-breadcrumb-item v-for="(item, index) in selectContainerLocation" :key="index">{{ item }}
          </el-breadcrumb-item>
        </el-breadcrumb>

        <div style="height: 16px"></div>
        <div v-if="menuType === 'outside_area' || menuType === 'fridge' || menuType === 'inside_area'">
          <!-- 非盒视图 -->
          <el-table
            v-loading="loading"
            :data="leafList"
            border
            max-height="740"
            show-summary
            size="small"
            stripe
            @row-dblclick="leafTableDbClick"
          >
            <el-table-column type="index" width="50"/>
            <el-table-column align="center" label="样本盒名称" prop="title"/>
            <el-table-column :show-overflow-tooltip="true" align="center" label="样本盒描述" prop="containerDesc"/>
            <el-table-column align="center" label="行数" prop="boxRow"/>
            <el-table-column align="center" label="列数" prop="boxColumn"/>
            <el-table-column align="center" label="位置" min-width="450" prop="containerLocation"/>
            <el-table-column align="center" label="当前样本数" prop="currentCount"/>
            <el-table-column align="center" label="可用孔格数" prop="totalCount"/>
          </el-table>
          <pagination
            v-show="total>0"
            :limit.sync="queryParams.pageSize"
            :page.sync="queryParams.pageNum"
            :total="total"
            @pagination="getLeafBoxes"
          />
        </div>
        <div v-else-if="menuType === 'boxes'">
          <el-row :gutter="24">
            <el-col :span="16">
              <el-table v-if="selectTubes && selectTubes.length > 0" ref="tubeTable" :data="selectTubes"
                        :row-style="{'height': 720/selectContainer.boxRow + 'px'}" border
                        class="customer-table" height="770px" style="width: 763px"
                        @cell-click="tableCellClick" @row-contextmenu="tableContextMenu"
              >
                <el-table-column align="center" type="index" width="42">
                  <template slot-scope="scope">
                    <span>{{ tubeRow[scope.$index] }}</span>
                  </template>
                </el-table-column>
                <el-table-column v-for="(item, index) in selectTubes" :key="index" :label="index + 1 + ''"
                                 :width="720/selectContainer.boxColumn"
                                 align="center"
                >
                  <template slot-scope="scope">
                    <el-popover
                      placement="right"
                      trigger="hover"
                      width="230"
                    >
                      <div v-if="scope.row[index].sample">
                        <div><span style="font-weight: 700">样本状态：{{ sampStateFormat(scope.row[index].sample) }}</span>
                        </div>
                        <div><span>复份编号：{{ scope.row[index].sample.sampBackupCode }}</span></div>
                        <div><span>样本源名称：{{ scope.row[index].sample.sampSourceName }}</span></div>
                        <div><span>样本类型名称：{{ scope.row[index].sample.sampTypeName }}</span></div>
                        <div><span>样本组：{{ scope.row[index].sample.sampGroupName }}</span></div>
                        <div><span>条码/二维码：{{ scope.row[index].sample.qrCode }}</span></div>
                      </div>
                      <svg-icon v-if="scope.row[index].sample"
                                slot="reference"
                                :class="scope.row[index].sample.sampState === '1' ? 'table-icon' : 'table-icon-blur'"
                                :icon-class="scope.row[index].sample.sampTypeIcon"
                      />
                    </el-popover>
                    <svg-icon v-if="scope.row[index].tubeState === '2'" class="table-icon" icon-class="disable"/>
                    <svg-icon v-if="scope.row[index].tubeState === '1'" class="table-icon" icon-class="broken"/>
                  </template>
                </el-table-column>
              </el-table>
            </el-col>
            <el-col :span="8">
              <el-button-group v-if="selectTubes && selectTubes.length > 0">
                <el-tooltip class="item" content="整盒添加到申领" effect="dark" placement="bottom">
                  <el-button v-hasPermi="['biobank:sample:edit']" icon="el-icon-sell" size="small" type="info"
                             @click="addAllToClaimStock"
                  >申领
                  </el-button>
                </el-tooltip>
                <el-tooltip class="item" content="整盒添加到出库" effect="dark" placement="bottom">
                  <el-button v-hasPermi="['biobank:sample:edit']" icon="el-icon-takeaway-box" size="small" type="info"
                             @click="addAllToOutStock"
                  >出库
                  </el-button>
                </el-tooltip>
                <el-tooltip class="item" content="整盒打印条码" effect="dark" placement="bottom">
                  <el-button v-hasPermi="['biobank:sample:print']" icon="el-icon-printer" size="small" type="primary"
                             @click="printAllSampleCode"
                  >打印
                  </el-button>
                </el-tooltip>
                <el-tooltip class="item" content="整盒录入二维码" effect="dark" placement="bottom">
                  <el-button v-hasPermi="['biobank:sample:edit']" size="small" type="success" @click="scanQrCode">
                    <svg-icon icon-class="scan"></svg-icon>
                    扫码
                  </el-button>
                </el-tooltip>
                <el-tooltip class="item" content="Excel导入二维码" effect="dark" placement="bottom">
                  <el-button v-hasPermi="['biobank:sample:edit']" icon="el-icon-upload2" size="small" type="warning"
                             @click="uploadByExcel"
                  >导入
                  </el-button>
                </el-tooltip>
                <el-tooltip class="item" content="整盒销毁样本" effect="dark" placement="bottom">
                  <el-button v-hasPermi="['biobank:sample:edit']" icon="el-icon-delete" size="small" type="danger"
                             @click="deleteAllSample"
                  >销毁
                  </el-button>
                </el-tooltip>
              </el-button-group>
              <!-- 样本信息 -->
              <el-card v-if="selectTubes && selectTubes.length > 0 && selectTube.sample"
                       style="position: relative; margin-top: 16px"
              >
                <div slot="header" class="clearfix">
                  <span>样本信息</span>
                </div>
                <el-form v-if="selectTube.sample && Object.keys(selectTube.sample).length > 0" class="sample-info"
                         label-position="left"
                >
                  <el-form-item label="样本复份编号">
                    <span>{{ selectTube.sample.sampBackupCode }}</span>
                  </el-form-item>
                  <el-form-item label="样本源编号">
                    <span>{{ selectTube.sample.sampSourceCode }}</span>
                  </el-form-item>
                  <el-form-item label="样本源名称">
                    <span>{{ selectTube.sample.sampSourceName }}</span>
                  </el-form-item>
                  <el-form-item label="样本类型">
                    <span>{{ selectTube.sample.sampTypeName }}</span>
                  </el-form-item>
                  <el-form-item label="样本组">
                    <span>{{ selectTube.sample.sampGroupName }}</span>
                  </el-form-item>
                  <el-form-item label="样本状态">
                    <span>{{ sampStateFormat(selectTube.sample) }}</span>
                  </el-form-item>
                  <el-form-item label="样本量">
                    <span>{{ selectTube.sample.sampQuantity }}{{ selectTube.sample.sampUnit }}</span>
                  </el-form-item>
                  <el-form-item label="条码/二维码">
                    <span>{{ selectTube.sample.qrCode }}</span>
                  </el-form-item>
                  <el-form-item label="采样时间">
                    <span>{{ selectTube.sample.samplingTime }}</span>
                  </el-form-item>
                </el-form>
              </el-card>
              <!-- 同样本其他复份信息 -->
              <el-card v-if="selectTubes && selectTubes.length > 0 && selectTube.sample" :body-style="{padding: '0px'}"
                       style="position: relative; margin-top: 16px"
              >
                <div slot="header" class="clearfix">
                  <span>同样本其他复份信息</span>
                </div>
                <el-table :data="selectTubeSameSamples" max-height="280" size="small">
                  <el-table-column align="center" label="复份编号" prop="sampBackupCode" width="110"/>
                  <el-table-column align="center" label="样本位置" prop="sampLocation"/>
                </el-table>
              </el-card>
            </el-col>
          </el-row>

          <div v-show="tableMenuVisible" id="tableRightMenu" @mouseleave="tableMenuVisible=!tableMenuVisible">
            <el-card>
              <div v-if="rightSelectTube.sample">
                <el-link v-hasPermi="['biobank:sample:query']" :underline="false" icon="el-icon-document"
                         @click="viewSampleDetail"
                >查看样本信息
                </el-link>
                <div style="height: 10px"></div>
                <el-link v-hasPermi="['biobank:sample:edit']" :underline="false" icon="el-icon-edit-outline"
                         @click="editSampleDetail"
                >编辑样本信息
                </el-link>
                <div style="height: 10px"></div>
                <el-link v-hasPermi="['biobank:sample:edit']" :underline="false" @click="addToClaimStock">
                  <svg-icon icon-class="samp-transfer" style="margin-right: 5px"/>
                  添加到申领
                </el-link>
                <div style="height: 10px"></div>
                <el-link v-hasPermi="['biobank:sample:edit']" :underline="false" @click="addToOutStock">
                  <svg-icon icon-class="samp-out" style="margin-right: 5px"/>
                  添加到出库
                </el-link>
                <div style="height: 10px"></div>
                <el-link v-hasPermi="['biobank:sample:edit']" :underline="false" icon="el-icon-document-delete"
                         @click="deleteSample"
                >销毁样本
                </el-link>
                <div style="height: 10px"></div>
                <el-link v-hasPermi="['biobank:sample:print']" :underline="false" icon="el-icon-printer"
                         @click="printSampleCode"
                >打印条码
                </el-link>
              </div>
              <div v-else>
                <div v-if="rightSelectTube.tubeState === '1'">
                  <el-link v-hasPermi="['biobank:tube:edit']" :underline="false" icon="el-icon-magic-stick"
                           @click="enableTube"
                  >使能试管
                  </el-link>
                </div>
                <div v-else>
                  <el-link v-hasPermi="['biobank:sample:edit']" :underline="false" @click="addToInStock">
                    <svg-icon icon-class="samp-in" style="margin-right: 5px"/>
                    样本入库
                  </el-link>
                  <div style="height: 10px"></div>
                  <el-link v-hasPermi="['biobank:tube:edit']" :underline="false" icon="el-icon-delete"
                           @click="abandonTube"
                  >废弃试管
                  </el-link>
                </div>
              </div>
              <div style="height: 10px"></div>
              <el-link :underline="false" icon="el-icon-document" @click="tubeHistory">孔格历史记录</el-link>
            </el-card>
          </div>
        </div>
        <div v-else>
          <i class="el-icon-s-flag" style="color: #1c84c6"> 点击左侧要查看的容器...</i>
        </div>
      </el-col>
    </el-row>

    <!-- 添加容器 -->
    <el-dialog :title="title" :visible.sync="open" append-to-body width="500px">
      <el-form ref="form" :model="form" :rules="rules" label-width="110px">
        <el-input v-if="false" v-model="form.containerId"/>
        <el-form-item :label="menuNameTitle" prop="containerName">
          <el-input v-model="form.containerName" placeholder="请输入名称" size="small"/>
        </el-form-item>
        <el-form-item :label="menuTypeTitle" prop="containerTypeId">
          <el-select
            v-model="form.containerTypeId"
            clearable
            placeholder="选择类型"
            size="small"
            style="width: 100%"
          >
            <el-option
              v-for="dict in containerTypeOptions"
              :key="dict.containerTypeId"
              :label="dict.containerTypeName"
              :value="dict.containerTypeId"
            />
          </el-select>
        </el-form-item>
        <el-form-item v-if="menuType !== 'outside_area'" label="存储样本类型">
          <treeselect
            v-model="form.sampleTypes"
            :clear-on-select="true"
            :clearable="true"
            :max-height="200"
            :multiple="true"
            :normalizer="normalizerSampType"
            :open-on-click="true"
            :options="sampleTypeOptions"
            placeholder="请选择样本类型"
            size="small"
            style="line-height: 16px"
          />
        </el-form-item>
        <el-form-item v-if="menuType === 'boxes'" label="冷冻盒行数" prop="boxRow">
          <el-input-number v-model="form.boxRow" :max="20" :min="1" controls-position="right" placeholder="请输入行数"
                           size="small" style="width: 100%"
          />
        </el-form-item>
        <el-form-item v-if="menuType === 'boxes'" label="冷冻盒列数" prop="boxColumn">
          <el-input-number v-model="form.boxColumn" :min="1" controls-position="right" placeholder="请输入列数" size="small"
                           style="width: 100%"
          />
        </el-form-item>
        <el-form-item v-if="menuType === 'boxes'" label="冷冻盒布局" prop="boxLayout">
          <el-radio-group v-model="form.boxLayout" size="small">
            <el-radio v-for="(item, index) in boxLayoutOptions"
                      :key="index" :label="item.dictValue"
            >{{ item.dictLabel }}
            </el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="同层级排序" prop="containerSort">
          <el-input-number v-model="form.containerSort" :max="1000" :min="1" controls-position="right"
                           placeholder="请输入同层级排序" size="small" style="width: 100%"
          />
        </el-form-item>
        <el-form-item label="描述" prop="containerDesc">
          <el-input
            v-model="form.containerDesc"
            :rows="2"
            placeholder="请输入描述"
            size="small"
            type="textarea"
          >
          </el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitForm">确 定</el-button>
        <el-button @click="cancel">取 消</el-button>
      </div>
    </el-dialog>
    <!-- 批量添加容器 -->
    <el-dialog :visible.sync="batchOpen" append-to-body title="批量添加容器分区" width="620px">
      <el-button type="text" @click="handleBatchAddition">添加分区</el-button>
      <el-row v-for="(item, index) in batchContainer.subareas" :key="index"
              :style="'margin-left: ' + (15 * index) + 'px;margin-top: 5px;'"
      >
        <el-col :span="11">
          <el-select
            v-model="item.containerTypeId"
            clearable
            placeholder="选择类型"
            size="small"
            style="width: 100%"
          >
            <el-option
              v-for="dict in batchContainerTypeOpts"
              :key="dict.containerTypeId"
              :label="dict.containerTypeName"
              :value="dict.containerTypeId"
            />
          </el-select>
        </el-col>
        <el-col :span="9" style="padding-left: 5px">
          <el-input v-model="item.count" onkeyup="value=value.replace(/[^\d]/g,'')" size="small">
            <template slot="prepend">数量</template>
          </el-input>
        </el-col>
        <el-col :span="4">
          <el-input v-if="false" v-model="item.parentId"></el-input>
          <i class="el-icon-remove" style="margin: 8px" @click="handleBatchDelete(item, index)"></i>
        </el-col>
      </el-row>
      <el-divider></el-divider>
      <div style="display: inline-table">
        <label style="margin-right: 10px">冻存盒数量</label>
        <el-input-number v-model="batchContainer.boxCount" :max="20" :min="1" controls-position="right" placeholder="数量"
                         size="small"
        />
        <label style="margin: 0px 10px">行数</label>
        <el-input-number v-model="batchContainer.boxRow" :max="20" :min="1" controls-position="right" placeholder="行数"
                         size="small"
        />
        <label style="margin: 0px 10px">列数</label>
        <el-input-number v-model="batchContainer.boxColumn" :max="20" :min="1" controls-position="right"
                         placeholder="列数" size="small"
        />
      </div>
      <div style="display: inline-table; margin-top: 10px">
        <label style="margin-right: 10px">冷冻盒布局</label>
        <el-radio-group v-model="batchContainer.boxLayout" size="small">
          <el-radio v-for="(item, index) in boxLayoutOptions"
                    :key="index" :label="item.dictValue"
          >{{ item.dictLabel }}
          </el-radio>
        </el-radio-group>
      </div>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitBatchAddition">确 定</el-button>
        <el-button @click="batchOpen = false">取 消</el-button>
      </div>
    </el-dialog>
    <!-- 复制容器 -->
    <el-dialog :title="title" :visible.sync="copyOpen" append-to-body width="500px">
      <el-form ref="copyForm" :model="copyForm" :rules="copyRules" label-width="110px">
        <el-input v-if="false" v-model="copyForm.containerId"/>
        <el-form-item :label="menuNameTitle" prop="containerName">
          <el-input v-model="copyForm.containerName" placeholder="请输入名称" size="small"/>
        </el-form-item>
        <el-form-item :label="menuTypeTitle" prop="containerTypeName">
          <el-input v-model="copyForm.containerTypeName" :disabled="true" size="small"></el-input>
        </el-form-item>
        <el-form-item v-if="menuType !== 'outside_area'" label="存储样本类型">
          <treeselect
            v-model="copyForm.sampleTypes"
            :clear-on-select="true"
            :clearable="true"
            :max-height="200"
            :multiple="true"
            :normalizer="normalizerSampType"
            :open-on-click="true"
            :options="sampleTypeOptions"
            placeholder="请选择样本类型"
            size="small"
            style="line-height: 16px"
          />
        </el-form-item>
        <el-form-item v-if="menuType === 'boxes'" label="冷冻盒行数" prop="boxRow">
          <el-input-number v-model="copyForm.boxRow" :disabled="true" :max="20" :min="1" controls-position="right"
                           placeholder="请输入行数" size="small" style="width: 100%"
          />
        </el-form-item>
        <el-form-item v-if="menuType === 'boxes'" label="冷冻盒列数" prop="boxColumn">
          <el-input-number v-model="copyForm.boxColumn" :disabled="true" :min="1" controls-position="right"
                           placeholder="请输入列数" size="small" style="width: 100%"
          />
        </el-form-item>
        <el-form-item v-if="menuType === 'boxes'" label="冷冻盒布局" prop="boxLayout">
          <el-radio-group v-model="copyForm.boxLayout" :disabled="true" size="small">
            <el-radio v-for="(item, index) in boxLayoutOptions"
                      :key="index" :label="item.dictValue"
            >{{ item.dictLabel }}
            </el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="描述" prop="containerDesc">
          <el-input
            v-model="copyForm.containerDesc"
            :rows="2"
            placeholder="请输入描述"
            size="small"
            type="textarea"
          >
          </el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitCopy">确 定</el-button>
        <el-button @click="cancelCopy">取 消</el-button>
      </div>
    </el-dialog>
    <!-- 修改样本复份 对话框 -->
    <el-dialog :visible.sync="updateOpen" append-to-body title="样本复份信息" width="60%">
      <el-form ref="updateForm" :disabled="updateDisable" :model="updateForm" :rules="updateRules" label-width="96px">
        <el-row>
          <el-col :span="12">
            <el-form-item label="样本类型" prop="sampTypeId">
              <treeselect v-model="updateForm.sampTypeId" :disabled="updateDisable" :normalizer="normalizerSampType"
                          :options="sampleTypeOptions" placeholder="请选择样本类型"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="样本组" prop="sampGroupId">
              <treeselect v-model="updateForm.sampGroupId" :disabled="updateDisable" :normalizer="normalizerSampGroup"
                          :options="sampleGroupOptions" placeholder="请选择样本组"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="样本量" prop="sampQuantity">
              <el-input v-model="updateForm.sampQuantity" placeholder="请输入样本量"/>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="样本单位" prop="sampUnit">
              <el-input v-model="updateForm.sampUnit" placeholder="请输入样本单位"/>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="冻存管类型" prop="tubeType">
              <el-select
                v-model="updateForm.tubeType"
                clearable
                placeholder="冻存管类型"
                size="small"
                style="width: 100%"
              >
                <el-option
                  v-for="dict in tubeTypeOptions"
                  :key="dict.dictValue"
                  :label="dict.dictLabel"
                  :value="dict.dictValue"
                />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="条码/二维码" prop="qrCode">
              <el-input v-model="updateForm.qrCode" placeholder="请扫码条码/二维码"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="24">
          <el-col :span="12">
            <el-form-item label="采样时间" prop="samplingTime">
              <el-date-picker v-model="updateForm.samplingTime" clearable
                              placeholder="选择采样时间"
                              size="small"
                              style="width: 100%"
                              type="datetime"
                              value-format="yyyy-MM-dd HH:mm:ss"
              >
              </el-date-picker>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitSample">确 定</el-button>
        <el-button @click="cancelSample">取 消</el-button>
      </div>
    </el-dialog>
    <!-- 挑选样本对话框 -->
    <sample-pick :can-create="true" :open="pickOpen" :samp-state="sampPickState" :single-choice="true"
                 @onClose="samplePickClose" @onConfirm="samplePickEvent"
    ></sample-pick>
    <!-- 孔格历史记录 -->
    <el-dialog :visible.sync="historyOpen" append-to-body title="孔格历史操作记录" width="60%">
      <tube-history :tube-id="rightSelectTube.tubeId"></tube-history>
    </el-dialog>
    <!-- excel导入二维码 对话框 -->
    <el-dialog :visible.sync="upload.open" append-to-body title="Excel导入" width="400px">
      <el-upload
        ref="upload"
        :auto-upload="false"
        :file-list="upload.updateFile"
        :limit="1"
        :on-change="handleUploadChange"
        :on-remove="handleUploadRemove"
        accept=".xlsx, .xls"
        action=""
        drag
      >
        <i class="el-icon-upload"></i>
        <div class="el-upload__text">
          将文件拖到此处，或
          <em>点击上传</em>
        </div>
        <div slot="tip" class="el-upload__tip">
          <el-checkbox v-model="upload.updateSupport"/>
          是否更新已经存在的二维码
          <el-link style="font-size:12px" type="info" @click="downloadTemplate">下载模板</el-link>
        </div>
        <div slot="tip" class="el-upload__tip" style="color:red">提示：仅允许导入“xls”或“xlsx”格式文件！</div>
      </el-upload>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitExcel">确 定</el-button>
        <el-button @click="upload.open = false">取 消</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import Treeselect from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import SamplePick from '@/views/biobank/sample/SamplePick'
import TubeHistory from '@/views/biobank/container/TubeHistory'
import {
  addContainer,
  batchAddContainer,
  copyContainer,
  delContainer,
  getContainer,
  getLeaf,
  lazyTree,
  updateContainer
} from '@/api/biobank/container'
import { listChildren } from '@/api/biobank/containerType'
import { confirmLocation, listTube, updateTube } from '@/api/biobank/tube'
import { getQrCodeTemplate, getSameSamples, updateSample, updateSamples } from '@/api/biobank/sample'
import { listSampleType } from '@/api/biobank/sampleType'
import { listSampleGroup } from '@/api/biobank/sampleGroup'
// import axios from 'axios'
import { getActiveTemp } from '@/api/tool/labelTemp'
import { hideLoading, showLoading } from '@/utils/loading'
import XLSX from 'xlsx'

export default {
  name: 'ContainerList',
  components: {
    Treeselect,
    SamplePick,
    TubeHistory
  },
  data() {
    return {
      publicPath: process.env.BASE_URL,
      rotation: {
        x: -Math.PI / 2,
        y: 0,
        z: 0
      },
      scale: {
        x: 0.8,
        y: 0.8,
        z: 0.8
      },
      // 遮罩层
      loading: false,
      // 总条数
      total: 0,
      // 查询参数
      queryParams: {
        pageNum: 1,
        pageSize: 20,
        containerId: undefined
      },
      // 容器 表格数据
      containerList: [],
      defaultProps: {
        children: 'children',
        label: 'title',
        isLeaf: 'leaf'
      },
      // 默认需要展开的菜单
      expandedKey: [],
      // 二维码excel导入
      upload: {
        // 是否显示弹出层
        open: false,
        // 是否更新已经存在的二维码
        updateSupport: false,
        // 上传的文件
        updateFile: []
      },
      // 弹出层标题
      title: '',
      // 菜单标题
      menuNameTitle: '',
      menuTypeTitle: '',
      // 是否显示弹出层
      open: false,
      // 批量添加弹出层
      batchOpen: false,
      // 修改样本复份弹出层
      updateOpen: false,
      // 挑选样本弹出层
      pickOpen: false,
      // 复制容器弹出层
      copyOpen: false,
      // 挑选样本的状态
      sampPickState: '0',
      // 历史记录弹出层
      historyOpen: false,
      // 修改样本复份弹出层 表单是否可编辑
      updateDisable: true,
      // 右键菜单是否显示
      menuVisible: false,
      // 表单参数
      form: {},
      // 修改样本复份表单
      updateForm: {},
      // 复制容器表单
      copyForm: {},
      // 右键菜单类型
      menuType: '',
      // 选中的容器
      selectContainer: {},
      // 选中容器树节点
      selectTreeNode: {},
      // 选中容器的逻辑位置
      selectContainerLocation: [],
      // 选中容器的冻存管数组
      selectTubes: [],
      // 选中容器的所有盒子数组
      leafList: [],
      // 点击选中的试管
      selectTube: {},
      // 选中的试管同样本其他复份信息
      selectTubeSameSamples: [],
      // 右键选中的试管
      rightSelectTube: {},
      // 容器类型
      containerTypeOptions: [],
      // 冻存盒布局
      boxLayoutOptions: [],
      // 样本状态
      sampStateOptions: [],
      // 批量添加容器层级
      batchContainer: {},
      // 批量添加容器-分区类型
      batchContainerTypeOpts: [],
      // 启用的打印标签模板
      activeLabelTemp: {},
      // 表单校验
      rules: {
        containerTypeId: { required: true, trigger: 'change', message: '容器类型不能为空' },
        containerSort: { required: true, trigger: 'blur', message: '同层级排序不能为空' },
        boxRow: { required: true, trigger: 'blur', message: '冷冻盒行数大小要在1到20之间' },
        boxColumn: { required: true, trigger: 'blur', message: '冷冻盒列数要大于1' },
        boxLayout: { required: true, trigger: 'change', message: '冷冻盒布局不能为空' },
        containerName: { max: 50, trigger: 'blur', message: '不能超过50个字符' },
        containerDesc: { max: 50, trigger: 'blur', message: '不能超过50个字符' },
        containerLevel: { required: true, trigger: 'blur', message: '同层级排序上限1000' }
      },
      // 修改样本复份表单校验
      updateRules: {
        sampTypeId: { required: true, trigger: 'change', message: '样本类型不能为空' },
        sampGroupId: { required: true, trigger: 'change', message: '样本组不能为空' },
        tubeType: { required: true, trigger: 'change', message: '冻存管类型不能为空' }
      },
      // 复制容器表单校验
      copyRules: {},
      // 样本类型 树选项
      sampleTypeOptions: [],
      // 样本组 树选项
      sampleGroupOptions: [],
      // 冻存管类型
      tubeTypeOptions: [],
      // 表格行值
      tubeRow: this.GLOBAL.TUBE_ROW,
      // 前一次选中的cell
      oldSelectTableCell: undefined,
      // 表格右键菜单
      tableMenuVisible: false,
      // 容器树节点 临时变量
      treeNode: {},
      treeResolve: {}
    }
  },
  created() {
    this.getDicts('box_layout').then(response => {
      this.boxLayoutOptions = response.data
    })
    this.getDicts('sample_state').then(response => {
      this.sampStateOptions = response.data
    })
    this.getDicts('tube_type').then(response => {
      this.tubeTypeOptions = response.data
    })
    this.getSampleTypeList()
    this.getSampleGroupList()
    this.getActiveLabelTemp()
  },
  methods: {
    // excel导入二维码
    uploadByExcel() {
      if (!this.selectTubes || this.selectTubes.length === 0) {
        this.$message.warning('请先选择冻存盒')
        return false
      }
      this.upload.open = true
      this.upload.updateSupport = false
      this.upload.updateFile = []
    },
    // 文件上传
    handleUploadChange(file, fileList) {
      this.upload.updateFile = [file]
    },
    // 文件删除
    handleUploadRemove(file, fileList) {
      this.upload.updateFile = []
    },
    // 下载模板
    downloadTemplate() {
      getQrCodeTemplate().then(response => {
        this.download(response.msg)
      })
    },
    // excel导入确定按钮点击事件
    submitExcel() {
      if (!this.upload.updateFile || this.upload.updateFile.length === 0) {
        this.$message.warning('请先上传Excel文件')
      }
      new Promise((resolve, reject) => {
        const reader = new FileReader()
        reader.onload = e => {
          const data = e.target.result
          const workbook = XLSX.read(data, { type: 'array' })
          const firstSheetName = workbook.SheetNames[0]
          const worksheet = workbook.Sheets[firstSheetName]
          const results = XLSX.utils.sheet_to_json(worksheet)

          if (results && results instanceof Array) {
            let samples = []
            let tubesArray = this.selectTubes.reduce((prev, next) => {
              return prev.concat(next)
            })
            tubesArray.forEach(item => {
              results.forEach(qr => {
                if (item.sample && item.tubeSort === qr.order && qr.code !== 'NoData') {
                  if (item.sample.qrCode && item.sample.qrCode !== '') {
                    if (this.upload.updateSupport) { // 已存在的二维码是否更新
                      item.sample.qrCode = qr.code
                    }
                  } else {
                    item.sample.qrCode = qr.code
                  }
                  samples.push(item.sample)
                }
              })
            })
            if (samples.length === 0) {
              this.$message.error('未获取到数据，请检查Excel文件')
              return false
            }
            this.convertArray(tubesArray)
            resolve(samples)
          } else {
            this.$message.warning('未获取到数据，请检查Excel文件')
          }
        }
        reader.readAsArrayBuffer(this.upload.updateFile[0].raw)
      }).then(samples => {
        this.upload.open = false
        return updateSamples(samples)
      }).then(res => {
        this.msgSuccess('更新二维码信息成功')
      }).catch(err => {
        this.upload.open = false
        this.$message.error('请导入正确的Excel文件')
      })
    },
    // 整盒扫码
    scanQrCode() {
      if (!this.selectTubes || this.selectTubes.length === 0) {
        this.$message.warning('请先选择冻存盒')
        return false
      }
      // axios.get('/scan-api/readResultData').then(res => {
      this.$jsonp('http://localhost:63668/readResultData', {
        callback: 'jsonp'
      }).then(res => {
        if (res.data && res.data instanceof Array) {
          let samples = []
          let tubesArray = this.selectTubes.reduce((prev, next) => {
            return prev.concat(next)
          })
          tubesArray.forEach(item => {
            res.data.forEach(qr => {
              if (item.sample && item.tubeSort === qr.order && qr.code !== 'NoData') {
                item.sample.qrCode = qr.code
                samples.push(item.sample)
              }
            })
          })
          this.convertArray(tubesArray)
          return samples
        } else {
          this.$message.warning('未获取到扫码结果，请正确放置冻存盒')
        }
      }).then(res => {
        return updateSamples(res)
      }).then(res => {
        this.msgSuccess('更新二维码信息成功')
      }).catch(err => {
        this.$message.error('请确认批量扫码仪是否连接正确或BarcodeReader是否打开')
      })
    },
    /** 懒加载容器 列表 */
    loadLazyTree(node, resolve) {
      if (node.level === 0) {
        this.treeNode = node
        this.treeResolve = resolve
        lazyTree(0).then(response => {
          resolve(response.data)
        })
      } else {
        lazyTree(node.data.containerId).then(response => {
          if (response.data && response.data.length > 0) {
            response.data.forEach(item => {
              if (item.containerTypeCode === 'box') {
                item.leaf = true
              }
            })
          }
          resolve(response.data)
        })
      }
    },
    // 获取选中容器下的所有盒子数据
    getLeafBoxes() {
      this.loading = true
      this.queryParams.containerId = this.selectContainer.containerId
      getLeaf(this.queryParams).then(response => {
        this.leafList = response.rows
        this.total = response.total
        this.loading = false
      })
    },
    // 选中容器下盒子列表双击事件
    leafTableDbClick(row, column, cell, event) {
      this.menuType = row.parentContainerTypeCode
      this.selectContainer = row
      if (row.containerLocation) {
        this.selectContainerLocation = row.containerLocation.substr(1).split('/')
      }
      this.selectTubes = []
      this.oldSelectTableCell = undefined
      if (this.menuType === 'boxes') {
        this.getTubes()
      }
    },
    // 编辑样本对话框 确定
    submitSample() {
      this.$refs['updateForm'].validate(valid => {
        if (valid) {
          updateSample(this.updateForm).then(response => {
            this.msgSuccess('修改成功')
            this.updateOpen = false
            this.rightSelectTube.sample.sampTypeId = this.updateForm.sampTypeId
            this.rightSelectTube.sample.sampGroupId = this.updateForm.sampGroupId
            this.rightSelectTube.sample.sampQuantity = this.updateForm.sampQuantity
            this.rightSelectTube.sample.sampUnit = this.updateForm.sampUnit
            this.rightSelectTube.sample.tubeType = this.updateForm.tubeType
            this.rightSelectTube.sample.samplingTime = this.updateForm.samplingTime
          })
        }
      })
    },
    // 编辑样本对话框 取消
    cancelSample() {
      this.updateOpen = false
    },
    // 查看样本详情
    viewSampleDetail() {
      this.resetUpdateForm()
      this.updateOpen = true
      this.updateDisable = true
      this.updateForm = this.rightSelectTube.sample
    },
    // 编辑样本
    editSampleDetail() {
      this.resetUpdateForm()
      this.updateOpen = true
      this.updateDisable = false
      this.updateForm = this.rightSelectTube.sample
    },
    // 添加到申领
    addToClaimStock() {
      let sample = this.rightSelectTube.sample
      if (sample.sampState !== this.GLOBAL.SAMPLE.NORMAL) { // '1'
        this.$message.warning('非正常在库样本无法添加到申领')
        return false
      }
      this.$confirm('是否确认添加"' + sample.sampBackupCode + '"到申领?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'info'
      }).then(() => {
        sample.sampState = this.GLOBAL.SAMPLE.TO_CLAIM // '6'
        return updateSample(sample)
      }).then(() => {
        this.this.rightSelectTube.sample.sampState = this.GLOBAL.SAMPLE.TO_CLAIM // '6'
        this.msgSuccess('添加成功')
      })
    },
    // 添加整盒到申领
    addAllToClaimStock() {
      let samples = []
      let tubesArray = this.selectTubes.reduce((prev, next) => {
        return prev.concat(next)
      })
      this.$confirm('是否确认整盒添加到申领?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'info'
      }).then(() => {
        tubesArray.forEach(item => {
          if (item.sample && item.sample.sampState === this.GLOBAL.SAMPLE.NORMAL) { // '1'
            item.sample.sampState = this.GLOBAL.SAMPLE.TO_CLAIM // '6'
            samples.push(item.sample)
          }
        })
        return updateSamples(samples)
      }).then(() => {
        this.msgSuccess('添加成功')
        this.convertArray(tubesArray)
      })
    },
    // 添加到出库
    addToOutStock() {
      let sample = this.rightSelectTube.sample
      if (sample.sampState !== this.GLOBAL.SAMPLE.NORMAL) { // '1'
        this.$message.warning('非正常在库样本无法添加到出库')
        return false
      }
      this.$confirm('是否确认添加"' + sample.sampBackupCode + '"到出库?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'info'
      }).then(() => {
        sample.sampState = this.GLOBAL.SAMPLE.TO_OUT // '2'
        return updateSample(sample)
      }).then(() => {
        this.rightSelectTube.sample.sampState = this.GLOBAL.SAMPLE.TO_OUT // '2'
        this.msgSuccess('添加成功')
      })
    },
    // 添加整盒到出库
    addAllToOutStock() {
      let samples = []
      let tubesArray = this.selectTubes.reduce((prev, next) => {
        return prev.concat(next)
      })
      this.$confirm('是否确认整盒添加到出库?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'info'
      }).then(() => {
        tubesArray.forEach(item => {
          if (item.sample && item.sample.sampState === this.GLOBAL.SAMPLE.NORMAL) { // '1'
            item.sample.sampState = this.GLOBAL.SAMPLE.TO_OUT // '2'
            samples.push(item.sample)
          }
        })
        return updateSamples(samples)
      }).then(() => {
        this.msgSuccess('添加成功')
        this.convertArray(tubesArray)
      })
    },
    // 销毁样本
    deleteSample() {
      let sample = this.rightSelectTube.sample
      if (sample.sampState !== this.GLOBAL.SAMPLE.NORMAL) { // '1'
        this.$message.warning('非正常在库样本无法添加到销毁')
        return false
      }
      this.$confirm('是否确认添加"' + sample.sampBackupCode + '"到销毁?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        sample.sampState = this.GLOBAL.SAMPLE.TO_DESTROY // '8'
        return updateSample(sample)
      }).then(() => {
        this.rightSelectTube.sample.sampState = this.GLOBAL.SAMPLE.TO_DESTROY // '8'
        this.msgSuccess('添加成功')
      })
    },
    // 整盒销毁样本
    deleteAllSample() {
      let samples = []
      let tubesArray = this.selectTubes.reduce((prev, next) => {
        return prev.concat(next)
      })
      this.$confirm('是否确认整盒添加到销毁?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        tubesArray.forEach(item => {
          if (item.sample && item.sample.sampState === this.GLOBAL.SAMPLE.NORMAL) { // '1'
            item.sample.sampState = this.GLOBAL.SAMPLE.TO_DESTROY // '8'
            samples.push(item.sample)
          }
        })
        return updateSamples(samples)
      }).then(() => {
        this.msgSuccess('添加成功')
        this.convertArray(tubesArray)
      })
    },
    // 打印条码
    printSampleCode() {
      this.handlePrint([this.rightSelectTube.sample])
    },
    // 整盒打印条码
    printAllSampleCode() {
      let samples = []
      let tubesArray = this.selectTubes.reduce((prev, next) => {
        return prev.concat(next)
      })
      tubesArray.forEach(item => {
        if (item.sample && item.sample.qrCode && item.sample.qrCode !== '') {
          samples.push(item.sample)
        }
      })
      this.handlePrint(samples)
    },
    handlePrint(printSamples) {
      if (!printSamples || printSamples.length === 0) {
        this.$message.warning('请先选择需打印项')
        return false
      }
      if (!this.activeLabelTemp || !this.activeLabelTemp.labelTempContent) {
        this.$message.warning('当前不存在启用的打印模板')
        return false
      }

      let value = {}
      value.title = this.activeLabelTemp.labelTempName
      value.width = this.activeLabelTemp.labelWidth
      value.height = this.activeLabelTemp.labelHeight
      value.pageWidth = this.activeLabelTemp.labelPageWidth
      value.pageHeight = this.activeLabelTemp.labelPageHeight
      value.tempItems = JSON.parse(this.activeLabelTemp.labelTempContent).tempItems
      // this.$lodop.print(value, printSamples);
      this.$lodop.preview(value, printSamples)
    },
    // 获取当前启用的标签模板
    getActiveLabelTemp() {
      getActiveTemp().then(response => {
        this.activeLabelTemp = response.data
      })
    },
    // 样本入库
    addToInStock() {
      // 为了强制刷新子组件列表
      this.sampPickState = ''
      this.$nextTick(() => {
        this.sampPickState = '0'
        this.pickOpen = true
      })
    },
    // 选择样本对话框取消事件
    samplePickClose() {
      this.pickOpen = !this.pickOpen
    },
    // 样本挑选
    samplePickEvent(selection) {
      if (selection && Object.keys(selection).length > 0) {
        this.rightSelectTube.sample = selection
        this.rightSelectTube.sampBackupId = selection.sampBackupId
        selection.sampLocation = this.selectContainer.containerLocation + '/' + this.rightSelectTube.tubeLocation
        // 确认样本位置
        let confirmForm = {}
        confirmForm.sampleBackups = [selection]
        confirmForm.tubes = [this.rightSelectTube]
        confirmLocation(confirmForm).then(response => {
          this.pickOpen = false
        })
      }
    },
    // 废弃试管
    abandonTube() {
      this.tableMenuVisible = true
      let tube = this.rightSelectTube
      this.$confirm('是否确认废弃"' + this.rightSelectTube.tubeLocation + '"试管?', '警告', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        tube.tubeState = this.GLOBAL.TUBE.DISABLE // '1'
        return updateTube(tube)
      }).then(() => {
        this.rightSelectTube.tubeState = this.GLOBAL.TUBE.DISABLE // '1'
        this.msgSuccess('废弃成功')
      })
    },
    // 使能试管
    enableTube() {
      this.tableMenuVisible = true
      let tube = this.rightSelectTube
      this.$confirm('是否确认使能"' + this.rightSelectTube.tubeLocation + '"试管?', '警告', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        tube.tubeState = this.GLOBAL.TUBE.NORMAL // '0'
        return updateTube(tube)
      }).then(() => {
        this.rightSelectTube.tubeState = this.GLOBAL.TUBE.NORMAL // '0'
        this.msgSuccess('使能成功')
      })
    },
    // 孔格历史记录
    tubeHistory() {
      this.historyOpen = true
    },
    // tree节点点击事件
    nodeClick(object, Node, element) {
      this.menuType = object.parentContainerTypeCode
      this.selectContainer = object
      this.selectTreeNode = Node
      if (object.containerLocation) {
        this.selectContainerLocation = object.containerLocation.substr(1).split('/')
      }
      this.selectTubes = []
      this.oldSelectTableCell = undefined
      if (this.menuType === 'boxes') {
        this.getTubes()
      } else {
        this.getLeafBoxes()
      }
    },
    // 容器树存储率颜色
    judgeColor(rate) {
      if (rate === 0) {
        return 'color: #909399'
      } else if (rate >= 0 && rate < 40) {
        return 'color: #409EFF'
      } else if (rate >= 40 && rate < 60) {
        return 'color: #67C23A'
      } else if (rate >= 60 && rate < 80) {
        return 'color: #E6A23C'
      } else if (rate >= 80 && rate <= 100) {
        return 'color: #F56C6C'
      }
    },
    // 单元格点击事件
    tableCellClick(row, column, cell, event) {
      if (row[parseInt(column.label) - 1].tubeState === this.GLOBAL.TUBE.FORBIDDEN) { // '2' 禁用状态不允许点击
        return false
      }
      if (this.oldSelectTableCell) {
        this.oldSelectTableCell.removeAttribute('style')
      }
      this.selectTube = row[parseInt(column.label) - 1]
      cell.setAttribute('style', 'background:#409EFF')
      this.oldSelectTableCell = cell
      this.getSelectSameSamples(this.selectTube.sample)
    },
    // 获取同样本其他复份信息
    getSelectSameSamples(data) {
      this.selectTubeSameSamples = []
      if (!data || Object.keys(data).length === 0) {
        return false
      }
      getSameSamples(data).then(response => {
        this.selectTubeSameSamples = response.data
      })
    },
    // 行右键事件
    tableContextMenu(row, column, event) {
      if (row[parseInt(column.label) - 1].tubeState === this.GLOBAL.TUBE.FORBIDDEN) { // '2'
        return false
      }
      this.rightSelectTube = row[parseInt(column.label) - 1]
      event.preventDefault()// 阻止右键默认行为
      this.tableMenuVisible = true
      let menu = document.querySelector('#tableRightMenu')
      menu.style.cssText = 'position: fixed; left: ' + (event.clientX - 10) + 'px' + '; top: ' + (event.clientY - 15) + 'px; z-index: 999; cursor:pointer;'
    },
    // 获取冻存管
    getTubes() {
      listTube(this.selectContainer.containerId).then(response => {
        const tubes = response.data
        this.convertArray(tubes)
      })
    },
    // 一维数组转二维数组
    convertArray(tubes) {
      const row = this.selectContainer.boxRow
      const column = this.selectContainer.boxColumn
      this.selectTubes = []

      let itemArr = []
      tubes.forEach(tube => {
        // 如果小数组满了，创建一个新的小数组
        if (itemArr.length === column) {
          itemArr = []
        }
        // 如果小数组是空的，将小数组保存到大数组中
        if (itemArr.length === 0) {
          this.selectTubes.push(itemArr)
        }
        // 保存数据到小数组
        itemArr.push(tube)
      })
    },
    // 右键事件
    rightClick(MouseEvent, object, Node, element) {
      this.menuType = object.parentContainerTypeCode
      this.selectContainer = object
      this.menuVisible = true
      let menu = document.querySelector('#rightMenu')
      menu.style.cssText = 'position: fixed; left: ' + (MouseEvent.clientX - 10) + 'px' + '; top: ' + (MouseEvent.clientY - 15) + 'px; z-index: 999; cursor:pointer;'
    },
    // 刷新整tree
    refreshTree() {
      this.treeNode.childNodes = []
      this.loadLazyTree(this.treeNode, this.treeResolve)
    },
    // 刷新tree节点
    updateTree(id) {
      let node = this.$refs.containerTree.getNode(id).parent
      node.childNodes = []
      node.loaded = false
      node.expand()
    },
    // 添加分区
    addOutsideArea() {
      this.reset()
      this.menuType = 'outside_area'
      this.getContainerTypeByCode(this.menuType)
      this.title = '添加分区 '
      this.menuNameTitle = '分区名称'
      this.menuTypeTitle = '分区类型'
      this.open = true
      this.selectContainer = undefined
    },
    // 添加容器
    addTheContainer() {
      this.reset()
      switch (this.menuType) {
        case 'outside_area':
          this.title = '添加容器'
          this.menuNameTitle = '容器名称'
          this.menuTypeTitle = '容器类型'
          this.getContainerTypeByCode('fridge')
          break
        case 'fridge':
        case 'inside_area':
          this.title = '添加容器分区'
          this.menuNameTitle = '容器分区名称'
          this.menuTypeTitle = '容器分区类型'
          this.getContainerTypeByCode('inside_area')
          break
      }
      this.form.parentId = this.selectContainer.containerId
      this.open = true
    },
    // 批量添加容器
    batchAddition() {
      this.batchContainer = {
        subareas: [],
        parentId: undefined,
        boxCount: undefined,
        boxRow: undefined,
        boxColumn: undefined,
        boxLayout: undefined
      }
      this.batchOpen = true
      this.batchContainer.parentId = this.selectContainer.containerId
    },
    // 批量添加容器-添加子分区
    handleBatchAddition() {
      if (this.batchContainerTypeOpts.length === 0) {
        listChildren('inside_area').then(response => {
          this.batchContainerTypeOpts = response.data
        })
      }
      this.batchContainer.subareas.push({})
    },
    // 批量添加容器-删除子层级
    handleBatchDelete(item, index) {
      this.batchContainer.subareas.splice(index, 1)
    },
    // 批量添加容器提交
    submitBatchAddition() {
      showLoading()
      batchAddContainer(this.batchContainer).then(response => {
        hideLoading()
        this.$message.success('批量添加成功')
        this.batchOpen = false
      }, error => {
        hideLoading()
      })
    },
    // 添加冻存盒
    addTheBox() {
      this.reset()
      this.menuType = 'boxes'
      this.title = '添加冻存盒'
      this.menuNameTitle = '冻存盒名称'
      this.menuTypeTitle = '冻存盒类型'
      this.form.parentId = this.selectContainer.containerId
      this.getContainerTypeByCode(this.menuType)
      this.open = true
    },
    // 复制分区
    copyTheContainer() {
      this.resetCopyForm()
      this.menuType = 'outside_area' // 除了boxes的任意类型即可
      this.title = '复制分区 '
      this.menuNameTitle = '分区名称'
      this.menuTypeTitle = '分区类型'
      this.copyForm = this.selectContainer
      this.copyOpen = true
    },
    // 复制冻存盒
    copyTheBox() {
      this.resetCopyForm()
      this.menuType = 'boxes'
      this.title = '复制冻存盒 '
      this.menuNameTitle = '冻存盒名称'
      this.menuTypeTitle = '冻存盒类型'
      this.copyForm = this.selectContainer
      this.copyOpen = true
    },
    // 复制容器确定按钮点击事件
    submitCopy() {
      showLoading()
      copyContainer(this.copyForm).then(response => {
        hideLoading()
        this.msgSuccess('复制成功')
        this.copyOpen = false
        if (this.selectContainer && this.selectContainer.containerId) {
          this.updateTree(this.selectContainer.containerId)
        } else {
          this.refreshTree()
        }
      }, error => {
        hideLoading()
      })
    },
    // 复制按钮取消按钮点击事件
    cancelCopy() {
      this.copyOpen = false
      this.resetCopyForm()
    },
    // 修改容器
    updateTheContainer() {
      this.reset()
      listChildren(this.menuType).then(response => {
        this.containerTypeOptions = response.data
      })
      const containerId = this.selectContainer.containerId
      getContainer(containerId).then(response => {
        switch (this.menuType) {
          case 'outside_area':
            this.title = '修改分区'
            this.menuNameTitle = '分区名称'
            this.menuTypeTitle = '分区类型'
            break
          case 'fridge':
            this.title = '修改容器'
            this.menuNameTitle = '容器名称'
            this.menuTypeTitle = '容器类型'
            break
          case 'inside_area':
            this.title = '修改容器分区'
            this.menuNameTitle = '容器分区名称'
            this.menuTypeTitle = '容器分区类型'
            break
          case 'boxes':
            this.title = '修改冻存盒'
            this.menuNameTitle = '冻存盒名称'
            this.menuTypeTitle = '冻存盒类型'
            break
        }
        this.form = response.data
        this.open = true
      })
    },
    // 删除容器
    deleteTheContainer() {
      const containerId = this.selectContainer.containerId
      this.$confirm('是否确认删除容器 编号为"' + containerId + '"的数据项?', '警告', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(function() {
        return delContainer(containerId)
      }).then(() => {
        if (this.menuType === 'outside_area') {
          this.refreshTree()
        } else {
          this.updateTree(containerId)
        }
        this.msgSuccess('删除成功')
      })
    },
    // 根据编码获取子容器
    getContainerTypeByCode(containerTypeCode) {
      listChildren(containerTypeCode).then(response => {
        this.containerTypeOptions = response.data
        if (this.containerTypeOptions.length > 0) {
          this.form.containerTypeId = this.containerTypeOptions[0].containerTypeId
        }
      })
    },
    /** 提交按钮 */
    submitForm() {
      if (this.menuType === 'boxes' && this.form.boxRow % 1 !== 0) {
        this.$message.error('冻存盒行必须是整数')
        return false
      }
      if (this.menuType === 'boxes' && this.form.boxColumn % 1 !== 0) {
        this.$message.error('冻存盒列必须是整数')
        return false
      }
      if (this.form.containerSort % 1 !== 0) {
        this.$message.error('同级排序必须为整数')
        return false
      }
      this.$refs['form'].validate(valid => {
        if (valid) {
          if (this.form.containerId != null) {
            showLoading()
            updateContainer(this.form).then(response => {
              hideLoading()
              this.msgSuccess('修改成功')
              this.open = false
              this.updateTree(this.form.containerId)
            }, error => {
              hideLoading()
            })
          } else {
            addContainer(this.form).then(response => {
              this.msgSuccess('新增成功')
              this.open = false
              if (this.menuType === 'outside_area') {
                this.refreshTree()
              } else {
                this.updateTree(this.selectContainer.containerId)
              }
            })
          }
        }
      })
    },
    // 取消按钮
    cancel() {
      this.open = false
      this.reset()
    },
    /** 样本状态状态字典翻译 */
    sampStateFormat(row, column) {
      return this.selectDictLabel(this.sampStateOptions, row.sampState)
    },
    /** 查询样本类型 列表 */
    getSampleTypeList() {
      listSampleType().then(response => {
        this.sampleTypeOptions = this.handleTree(response.data, 'sampTypeId', 'parentId')
      })
    },
    /** 转换样本类型 数据结构 */
    normalizerSampType(node) {
      if (node.children && !node.children.length) {
        delete node.children
      }
      return {
        id: node.sampTypeId,
        label: node.sampTypeName,
        children: node.children
      }
    },
    /** 查询样本组 列表 */
    getSampleGroupList() {
      listSampleGroup().then(response => {
        this.sampleGroupOptions = this.handleTree(response.data, 'sampGroupId', 'parentId')
      })
    },
    /** 转换样本组 数据结构 */
    normalizerSampGroup(node) {
      if (node.children && !node.children.length) {
        delete node.children
      }
      return {
        id: node.sampGroupId,
        label: node.sampGroupName,
        children: node.children
      }
    },
    // 表单重置
    reset() {
      this.form = {
        containerId: undefined,
        parentId: undefined,
        containerTypeId: undefined,
        containerTypeCode: undefined,
        containerTypeName: undefined,
        containerName: undefined,
        containerDesc: undefined,
        containerLocation: undefined,
        containerSort: undefined,
        containerLevel: undefined,
        currentCount: undefined,
        totalCount: undefined,
        boxRow: undefined,
        boxColumn: undefined,
        boxLayout: undefined,
        boxBarcode: undefined,
        deviceId: undefined
      }
      this.resetForm('form')
    },
    // 表单重置
    resetUpdateForm() {
      this.updateForm = {
        sampTypeId: undefined,
        sampGroupId: undefined,
        sampQuantity: undefined,
        sampUnit: undefined,
        tubeType: undefined,
        samplingTime: undefined
      }
      this.resetForm('updateForm')
    },
    // 复制容器表单重置
    resetCopyForm() {
      this.copyForm = {
        containerId: undefined,
        parentId: undefined,
        containerTypeId: undefined,
        containerTypeName: undefined,
        containerName: undefined,
        containerDesc: undefined,
        containerLocation: undefined,
        containerSort: undefined,
        currentCount: undefined,
        totalCount: undefined,
        boxRow: undefined,
        boxColumn: undefined,
        boxLayout: undefined,
        boxBarcode: undefined
      }
      this.resetForm('copyForm')
    }
  }
}
</script>
<style scoped>
.box-card {
  height: 820px;
  overflow: auto;
  font-size: 15px;
}

.box-tree {
  padding-bottom: 100px;
}

.table-icon {
  position: absolute;
  top: 5%;
  left: 5%;
  right: 5%;
  bottom: 5%;
  width: 90%;
  height: 90%;
  object-fit: cover;
}

.table-icon-blur {
  position: absolute;
  top: 5%;
  left: 5%;
  right: 5%;
  bottom: 5%;
  width: 90%;
  height: 90%;
  object-fit: cover;
  -webkit-filter: blur(2px);
}

.el-table--scrollable-x .el-table__body-wrapper {
  overflow-x: hidden;
}

ul {
  list-style-type: none;
}

.outside-list li {
  float: left;
  width: 30%;
  text-align: center;
  height: 180px;
  line-height: 180px;
  color: #666;
  border: 1px solid #eee;
  margin: -1px;
}

.sample-info {
  font-size: 0;
}

.sample-info label {
  width: 90px;
  color: #99a9bf;
}

.sample-info {
  margin-right: 0;
  margin-bottom: 0;
}

.el-tree {
  min-width: 100%;
  display: inline-block;
}

.el-button {
  padding: 10px 12px;
}

.sample-info .el-form-item {
  margin-bottom: 0;
}
</style>
